<?php


namespace app\service;


use app\lib\exception\ServiceException;
use app\utils\DateTime;
use think\facade\Db;

class ReservationService
{
    private $RoomService;
    private $DepositStatusService;
    private $OrderService;
    private $PayOrderService;
    private $UsingRoomTimeService;
    private $RoomPasswordService;
    private $DateTime;

    public function __construct()
    {
        $this->RoomService = new RoomService();
        $this->DepositStatusService = new DepositStatusService();
        $this->OrderService = new OrderService();
        $this->PayOrderService = new PayOrderService();
        $this->UsingRoomTimeService = new UsingRoomTimeService();
        $this->RoomPasswordService = new RoomPasswordService();
        $this->DateTime = new DateTime();
    }

    public function gerReservation($id , $status = false){
        $OrderModel = $this->OrderService->getOrder($id , $status);
        $RoomModel = $this->RoomService->getRoom($OrderModel->room_id);
        $DepositStatusModel = $this->DepositStatusService->getDepositStatus($OrderModel->pay_id);
        $UsingRoomTimeModel = $this->UsingRoomTimeService->getUsingRoomTime($OrderModel->usingroom_time_id);
        $PayOrderModel = $this->PayOrderService->getPayOrder($DepositStatusModel->id);
        if ($status){
            unset($RoomModel->RoomPassword);
        }else{
            $RoomPasswordModel = $this->RoomPasswordService
                ->getRoomPasswordStartBetweenEndTime($RoomModel->id , time() , $UsingRoomTimeModel->start_time , $UsingRoomTimeModel->end_time);
            $RoomModel->RoomPassword = $RoomPasswordModel;
        }
        $data = [];

        $data['Room'] = $RoomModel;
        $data['DepositStatus'] = [
            'get_time' => $DepositStatusModel->get_time,
            'deposit' => $DepositStatusModel->return_pay,
            'status' => $DepositStatusModel->status
        ];
        $data['Reservation'] = [
            'day' => $UsingRoomTimeModel->day,
            'start_time' => $UsingRoomTimeModel->start_time,
            'end_time' => $UsingRoomTimeModel->end_time,
            'price' => $PayOrderModel->money,
        ];

        return $data;
    }

    public function gerReservationAll($user_id , $status = false){
        $models = $this->OrderService->getOrderByUserId($user_id , $status);
        if (!$status){
            foreach ($models as $model){
                $password = $this->RoomPasswordService->getRoomPasswordStartBetweenEndTime($model->room_id , time());
                if ($password == null)$password =  $this->RoomPasswordService
                    ->getRoomPasswordByTime($model->UsingRoomTime->start_time , $model->UsingRoomTime->end_time , $model->Room->id);
                $model->room->password = $password;
            }
        }
        return $models;
    }

    public function reservation($user_id , $room_id , $deposit , $price , $start_time , $end_time , $pay_remarks = ''){
        try {
            Db::startTrans();
            $roomModel = $this->RoomService->getRoom($room_id);
            if ($roomModel == null) throw new ServiceException("房间不存在");
            if ($roomModel->status == '已出租') throw new ServiceException("房间已出租");
            // Todo ： 支付模块暂时写不了 先用这个代替支付验证
            if ($roomModel->old_price != $deposit)throw new ServiceException('支付失败');

            // 修改房间已经为已经出租
            $this->RoomService->editRoom($roomModel->id , ['status' => 1]);
            // 添加使用房间记录
            $UsingRoomTimeModel = $this->UsingRoomTimeService
                ->addUsingRoomTime($roomModel->id , $start_time , $end_time);
            // 定金表记录
            $DepositStatusModel = $this->DepositStatusService
                ->addDepositStatus($deposit , time() , 1 , $pay_remarks);
            // 价格表记录
            $PayOrderModel = $this->PayOrderService
                ->addPayOrder($user_id , $DepositStatusModel->id , $price , 0);
            // 管理表记录
            $OrderModel = $this->OrderService
                ->addOrder($user_id , $DepositStatusModel->id , $roomModel->id , $UsingRoomTimeModel->id , null , $DepositStatusModel->status);

            Db::commit();
        }catch (\Exception $exception){
            Db::rollback();
            throw new ServiceException($exception->getMessage());
        }
        return $this->gerReservation($OrderModel->id);
    }

    public function unsubscribe($id){
        try {
            Db::startTrans();
            $OrderModel = $this->OrderService->getOrder($id);
            // 将房间改回可以出租
            $this->RoomService->editRoom($OrderModel->room_id , ['status' => 0]);
            // 修改租金状态
            $DepositStatusModel = $this->DepositStatusService->editDepositStatus($OrderModel->pay_id , ['status' => '3']);
            // 退租
            $this->OrderService->editOrder($id , ['deposit_status' => $DepositStatusModel->status]);
            $this->OrderService->delOrder($id);
            Db::commit();
        }catch (\Exception $exception){
            Db::rollback();
            throw new ServiceException($exception->getMessage());
        }
        return;
    }
}